﻿using DryIoc;
using Prism.DryIoc;
using Prism.Ioc;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using ZoneLinePacking.Common;
using ZoneLinePacking.Core;
using ZoneLinePacking.Core.Helpers;
using ZoneLinePacking.Core.Utils;
using ZoneLinePacking.Services.DB;
using ZoneLinePacking.Services.Message;
using ZoneLinePacking.Services.Print;
using ZoneLinePacking.ViewModels;
using ZoneLinePacking.ViewModels.Dialogs;
using ZoneLinePacking.Views;
using ZoneLinePacking.Views.Dialogs;

namespace ZoneLinePacking {
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : PrismApplication {

        protected override Window CreateShell() {
            //UI线程未捕获异常处理事件
            App.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
            //非UI线程未捕获异常处理事件(例如自己创建的一个子线程) App.config中加了legacyUnhandledExceptionPolicy 则不会进
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            //Task线程内未捕获异常处理事件
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
            //防止系统休眠
            WinSleepUtil.PreventForCurrentThread();


            return Container.Resolve<MainWindow>();
        }


        protected override void RegisterTypes(IContainerRegistry containerRegistry) {

            #region 注册服务
            containerRegistry.RegisterSingleton<IMessageService, MessageService>();

            //DB部分Service
            containerRegistry.RegisterSingleton<IFreeSqlMainContext, FreeSqlMainContext>();
            containerRegistry.RegisterSingleton<IDbOperate<IFreeSqlMainContext>, DbOperate<IFreeSqlMainContext>>();
            containerRegistry.RegisterSingleton<PrinterBoxCodeService>();//箱码打印服务

            #endregion

            #region 导航
            //主程序
            containerRegistry.RegisterForNavigation<MainWindow, MainWindowModel>(nameof(ZoneLinePacking.MainWindow));
            containerRegistry.RegisterForNavigation<MainPackingView, MainPackingViewModel>(nameof(MainPackingView)); //装箱中心

            containerRegistry.RegisterForNavigation<LabelBoxCodePrintView, LabelBoxCodePrintViewModel>(nameof(LabelBoxCodePrintView));//箱码打印
            containerRegistry.RegisterForNavigation<LabelBoxCodeSettingView, LabelBoxCodeSettingViewModel>(nameof(LabelBoxCodeSettingView));//箱码模板
            #endregion

            #region 弹框
            //登录
            containerRegistry.RegisterDialog<LoginDialogView, LoginDialogViewModel>(nameof(LoginDialogView));
            //选型
            containerRegistry.RegisterDialog<SelectProductDialogView, SelectProductDialogViewModel>(nameof(SelectProductDialogView));
            //模板信息编辑
            containerRegistry.RegisterDialog<EditTemplateDialogView, EditTemplateDialogViewModel>(nameof(EditTemplateDialogView));
            //批量打印
            containerRegistry.RegisterDialog<BatchPrintDialogView, BatchPrintDialogViewModel>(nameof(BatchPrintDialogView));
            //箱码打印
            containerRegistry.RegisterDialog<BoxCodePrintDialogView, BoxCodePrintDialogViewModel>(nameof(BoxCodePrintDialogView));
            //密码授权
            containerRegistry.RegisterDialog<AuthDialogView, AuthDialogViewModel>(nameof(AuthDialogView));
            //继续装箱
            containerRegistry.RegisterDialog<ContinueBoxUpDialogView, ContinueBoxUpDialogViewModel>(nameof(ContinueBoxUpDialogView));
            #endregion
        }


        protected override void OnInitialized() {

            Process proCurrent = Process.GetCurrentProcess();
            var pros = Process.GetProcesses();

            if (pros == null || pros.Length < 1) {
                return;
            }
            if (pros.Count(p => p.ProcessName == proCurrent.ProcessName) > 1) {
                LogManager.Error("软件已启动，只能同时运行一个软件");
                Environment.Exit(0);
            }

#if DEBUG
            DBHelper.CraeteData();
#endif

            //设置系统语言&皮肤
            AppSession.InitAppConfig();

            //设置默认语言
            //GlobalData.Config.Lang = "en";
            //UpdateLang(GlobalData.Config.Lang);

            #region Login
            PrismIocInfo.DialogService.ShowDialog(nameof(LoginDialogView), new DialogParameters() { { "Title", AppSession.AppactionName } }, rhs => {
                if (rhs.Result != ButtonResult.OK) {
                    WinSleepUtil.RestoreForCurrentThread();
                    Environment.Exit(0);
                }
            });
            #endregion

            base.OnInitialized();
        }


        protected override void OnExit(ExitEventArgs e) {

            //调用基类的 OnExit 方法来执行默认退出逻辑
            base.OnExit(e);

            //显式调用 Shutdown，如果需要强制退出
            //Application.Current.Shutdown();
        }


        #region 异常处理
        private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) {
            LogManager.Error("UI线程内未捕获异常处理事件", e.Exception);
            try {
                //PrismIocInfo.MessageService?.GrowError(e.Exception.Message);
                e.Handled = true; //把 Handled 属性设为true，表示此异常已处理，程序可以继续运行，不会强制退出
            } catch (Exception ex) {
                LogManager.Error("UI线程内未捕获异常处理事件catch", ex);
            }
        }

        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) {
            if (e.Exception is Exception exception) {
                LogManager.Error("Task线程内未捕获异常处理事件", exception);
            }
            //e.SetObserved();//设置该异常已察觉（这样处理后就不会引起程序崩溃）
        }

        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
            if (e.ExceptionObject is Exception exception) {
                LogManager.Error("非UI线程未捕获异常处理事件", exception);
            }
        }
        #endregion
    }

}
